package com.lenovo.wxtoken.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lenovo.wxtoken.annotation.OauthCache;
import com.lenovo.wxtoken.entity.OauthCacheSin;
import com.lenovo.wxtoken.service.EmailService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.mail.MessagingException;
import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class OauthCacheAOP {
    private OauthCacheSin ocs = OauthCacheSin.getInstance();
    
    @Autowired
    EmailService emailService;

    @Pointcut("@annotation(com.lenovo.wxtoken.annotation.OauthCache)")
    public void getCache() {
    }

    @Around("getCache()&&@annotation(oauthCache)")
    public Object beforeExec (ProceedingJoinPoint joinPoint, OauthCache oauthCache) {
        String prefix = oauthCache.prefix();
        String key = oauthCache.key();
        String name = joinPoint.getSignature().getName();
        if(StringUtils.isEmpty(key)) {
            //默认策略生成key  方法名加参数值
            key = name;
            Object[] args = joinPoint.getArgs();

            for (Object arg : args) {
                key += String.valueOf(arg);
            }
        }

        //读取缓存  key增加前缀 避免与其他信息冲突
        String result = ocs.get(prefix + "_" + key);

        if(StringUtils.isEmpty(result)){
            try {
                result = String.valueOf(joinPoint.proceed());
                if (StringUtils.isEmpty(result)) {
                    sendAlerts(joinPoint, new Exception("获取结果为空"));
                } else {
                    ocs.put(oauthCache.prefix() + "_" + key, result);
                }

            } catch (Throwable throwable) {
                log.error("{} proceed error, {}", name, throwable.getMessage());
                throwable.printStackTrace();
                sendAlerts(joinPoint, throwable);
            }
        }

        return result;
    }

    //发送报警
    public void sendAlerts(ProceedingJoinPoint joinPoint, Throwable e){
        try {
            JSONObject o = new JSONObject();
            o.fluentPut("functionName", joinPoint.getSignature().getName())
                    .fluentPut("args", Arrays.toString(joinPoint.getArgs()));
            emailService.sendEmail("错误参数为：" + o.toJSONString() + "错误信息为：" + JSON.toJSONString(e));
        } catch (MessagingException e1) {
            e1.printStackTrace();
        }
    }

}
